import echartDefault from './echart-property-default.js';
import {
  isObject,
  isArray,
  mergeObj,
  convertValue,
  timeFormat,
  permil,
  isNum,
  numFormat,
  objHas,
  getObjFromJson,
} from '@/utils/util.js';
import { markLineTypes } from './form-item-options.js';
import { orderBy } from 'lodash';

export default {

  /**
   * 获取默认值
   * @param  {String}  path      属性路径
   *                             如："echart.xAixs.splitLine.show"
   *                             如：echart.series.0.markLine.data.0.type
   * @return {Mix}
   */
  getDfVal(path, form, serieType) {
    let val = form || echartDefault;
    const _serieType = serieType || '';
    let _path = path;

    if (form === echartDefault) {
      // 转换： echart.series.0.markLine.data.0.type => echart.series.line.markLine.data.type
      _path = _path.replace(/\.\d+\./g, '.');
      if (_serieType) {
        _path = _path.replace('series.', `series.${_serieType}.`);
      }
    }

    const arr = _path.split('.');
    const len = arr.length;
    for (let i = 0; i < len; i++) {
      const key = arr[i];
      if (!objHas(val, key)) {
        return undefined;
      }
      val = val[key];
      if (i === len - 1) {
        return val;
      }
    }
    return null;
  },

  /**
   * 获取私有配置属性路径
   * @param  {string} path 如： echart.xAxis.axisLabel.interval
   *                       如： echart.series.0.markLine.data.0.type
   *                       如： echart.series.0.radius.0
   *
   * @return {string}      如： echart.xAxis.axisLabel._interval
   *                       如： echart.series.0.markLine.data.0._type
   *                       如： echart.series.0._radius_0
   */
  getPropConfPath(path, formIsArr = false) {
    const arr = path.split('.');
    const prevKey = arr[arr.length - 2] || '';
    const lastKey = arr[arr.length - 1];
    if (formIsArr) {
      arr.pop();
      arr[arr.length - 1] = `_${prevKey}_${lastKey}`;
    } else {
      arr[arr.length - 1] = `_${lastKey}`;
    }
    const _path = arr.join('.');
    return _path;
  },

  /**
   * 获取echart属性私有配置值（开关，单位，主题色对应值）
   * @param  {string} path  如：echart.xAxis.axisLabel.interval
   *                        如：echart.series.0.markLine.data.0.type
   *                        如：echart.series.0.radius.0
   *
   * @param  {string} key   对应私有属性对象中(echart.xAxis.axisLabel._interval)的子属性key，
   *                        如： switch | unit | light | dark
   * @param  {object} form  总对象, 如 confing.property
   * @param  {stirng} serieType  图表类型，如： bar | line | pie | scatter
   * @return {mix}
   */
  getPropConfVal(path, key, form, serieType, formIsArr = false) {
    const _path = this.getPropConfPath(path, formIsArr);
    const _dfConf = this.getDfVal(_path, echartDefault, serieType) || {};
    let _conf = {};
    if (form) {
      _conf = this.getDfVal(_path, form, serieType) || {};
    }

    _conf = { ..._dfConf, ..._conf };

    const dfVal = this.getDfVal(path, echartDefault, serieType);
    if (dfVal === 'auto' && !_conf.switch) {
      _conf.switch = false;
    }

    if (Object.keys(_conf).length === 0) {
      return undefined;
    }

    if (key) {
      return _conf[key];
    }
    return _conf;
  },

  /**
   * 获取默认颜色
   * @param  {String} path           属性路径，如："echart.xAixs.splitLine.lineStyle.color"
   * @param  {String} componentStyle 主题，light | dark
   * @return {String}
   */
  getDfColor(path, componentStyle, serieType) {
    const color = this.getPropConfVal(path, componentStyle, '', serieType);
    return color;
  },

  /**
   * 注册变量，抽象公用方法
   * @param  {string} path    属性路径，如: "echart.grid.top" | "echart.series.0.markLine"
   * @param  {object} topForm 属性对象，如: config.property
   * @param  {object} vm      vue实例对象
   * @param  {mix}    val     属性值
   */
  registerVar(path, topForm, vm, val) {
    const arr = path.split('.');
    const len = arr.length;
    let form = topForm;
    for (let i = 0; i < len; i++) {
      const key = arr[i];
      const nextKey = arr[i + 1];
      if (!objHas(form, key)) {
        let _val;
        if (i === len - 1) {
          form[key] = val;
        } else {
          const emptyObj = {}; // 规避最大深度
          if (key !== 'series' && /^\d+$/.test(nextKey)) {
            // series.0中的0
            form[key] = [];
          } else {
            form[key] = emptyObj;
          }
        }
      }
      form = form[key];
      if (form) {
      }
    }
    return form;
  },

  _clearNoUseProps(val) {
    for (const i in val) {
      if (val[i] === 'auto' || val[i] === null) {
        delete val[i];
      }
    }
  },

  // 巨大函数拆分优化
  _setItem(params) {
    const { form, pForm, i, vm, path, topForm, len, serieType } = params;
    const arr = path.split('.');
    const key = arr[i];
    const prevKey = arr[i - 1] || '';
    const nextKey = arr[i + 1];
    let val;
    if (i === len - 1) {
      const isArr = isArray(form);
      const { componentStyle } = topForm;
      if (componentStyle) {
        val = this.getPropConfVal(path, componentStyle, topForm, serieType, isArr);
      }
      if (typeof val === 'undefined') {
        val = this.getDfVal(path, echartDefault, serieType);
      }
      if (isObject(val)) {
        val = JSON.parse(JSON.stringify(val));
        this._clearNoUseProps(val);
      }
      form[key] = val;
      const _conf = this.getPropConfVal(path, '', topForm, serieType, isArr);
      if (_conf) {
        let _key = `_${key}`;
        if (isArr) {
          _key = `_${prevKey}_${key}`;
          if (!pForm[_key]) {
            pForm[_key] = {};
          }
          Object.entries(_conf).map(([j]) => {
            pForm[_key][j] = _conf[j];
          });
        } else {
          if (!form[_key]) {
            form[_key] = {};
          }
          Object.entries(_conf).map(([j]) => {
            form[_key][j] = _conf[j];
          });
        }
      }
      const requires = this.getPropConfVal(path, 'require', topForm, serieType, isArr);
      if (requires) {
        requires.forEach(n => {
          this.register(n, topForm, vm);
        });
      }
    } else {
      val = key !== 'series' && /^\d+$/.test(nextKey) ? [] : {};
      form[key] = val;
    }
  },

  /**
   * 注册属性，echart属性公用方法
   * @param  {string} path    属性路径，如: "echart.grid.top"
   * @param  {object} topForm 属性对象，如: config.property
   * @param  {object} vm      vue实例对象
   */
  register(path, topForm, vm, serieType) {
    const arr = path.split('.');
    const len = arr.length;
    let form = topForm;
    let pForm = topForm;
    for (let i = 0; i < len; i++) {
      const key = arr[i];
      if (!objHas(form, key)) {
        this._setItem({ form, pForm, i, vm, path, topForm, len, serieType });
      }
      pForm = form;
      form = form[key];
    }
    return true;
  },

  /**
   * 合并property.echart对象属性
   * @param  {object} option -- chart-option.js中的option对象
   * @param  {object} orgEchart -- property.echart对象
   * @return {object}        合并完后的option对象
   */
  mergeEchartOrgOptions(option, orgEchart, emptyName) {
    if (!orgEchart) {
      return option;
    }
    const echart = JSON.parse(JSON.stringify(orgEchart));
    if (!echart.series) {
      echart.series = {};
    }
    const seriesArr = option.series.map(n => ({ name: n.name }));

    /*
     * echart.series 是对象，非数组
     * 数字型属性 series.1
     */
    for (const i in echart.series) {
      if (/^\d+$/.test(i)) {
        seriesArr[i] = { ...seriesArr[i], ...echart.series[i] };
      }
    }

    // 非数字型属性，series.label.show
    const excludes = { markLine: null, markArea: null, _labels: null };
    for (const i in echart.series) {
      if (!/^\d+$/.test(i)) {
        if (!objHas(excludes, i)) {
          seriesArr.forEach(n => {
            n[i] = echart.series[i];
          });
        } else {
          excludes[i] = echart.series[i];
        }
      }
    }

    echart.series = JSON.parse(JSON.stringify(seriesArr));
    for (const i in excludes) {
      if (excludes[i]) {
        echart.series[i] = excludes[i];
      }
    }

    this.fixLegendPos(option, echart);
    this.fixEchartMarkLine(echart);
    this.fixEchartMarkArea(echart);
    this.fixEchartValues(echart);
    this.fixMinMax(echart);

    // 合并属性
    this.mergeBasic(option, echart);
    this.mergeLegendSeries(option, echart);
    this.mergeSeries(option, echart);
    this.mergeSeriesLabels(option, echart);
    this.mergeDataZoom(option, echart);
    this.mergeSplitLine(option, echart);

    this.fixBar(option);
    this.fixSerieDataBySerieType(option, echart, emptyName);
    this.fixPie(option);
    this.fixSerieLabelFormater(option);
    this.fixTimeAxisLabel(option);
    this.fixLegend(option);
    this.replaceLineWrap(option);

    return option;
  },

  fixMinMax(echart) {
    this._toNum(echart, 'xAxis.min');
    this._toNum(echart, 'xAxis.max');
    this._toNum(echart, 'yAxis.min');
    this._toNum(echart, 'yAxis.max');
    this._toNum(echart, 'yAxis.0.min');
    this._toNum(echart, 'yAxis.0.max');
    this._toNum(echart, 'yAxis.1.min');
    this._toNum(echart, 'yAxis.1.max');
  },

  // 字符串数字转数值
  _toNum(obj, path) {
    const arr = path.split('.');
    let val = obj;
    let pObj = obj;
    let key = '';
    for (let i = 0; i < arr.length; i++) {
      key = arr[i];
      if (val[key] === undefined) {
        return;
      }
      pObj = val;
      val = val[key];
    }
    if (isNum(val)) {
      pObj[key] = Number(val);
    }
  },

  fixEchartMarkLine(echart) {
    // 按系列名分配 markLine
    const markLine = echart.series && echart.series.markLine;

    const itemFn = (n, i) => {
      n.label.color = n.lineStyle.color;
      let serie = echart.series.find(n1 => n1.name === n._serieName);
      if (!serie && !n._serieName) {
        serie = echart.series[0];
      }
      if (serie) {
        if (!serie.markLine) {
          serie.markLine = {
            ...markLine,
            symbol: n._symbol,
            data: [],
          };
        }
        serie.markLine.data.push(n);
      }
    };

    if (markLine) {
      markLine.data.forEach((n, i) => {
        itemFn(n, i);
      });
    }

    /*
     * 根据_value, _axisType修正
     * ------------ markLine
     * {type:'min', name:'最小值', valueIndex:0}, // x轴参考线
     * {type:'min', name:'最小值', valueIndex:1}, // y轴参考线
     * {yAxis:100, name:'最小值'}, // y轴参考线，
     * {xAxis:'100', name:'最小值'}, // x轴参考线，必须是字符串，因为轴类型是category
     */

    const itemFn2 = n1 => {
      if (markLineTypes.some(n2 => n2.value === n1._value)) {
        n1.type = n1._value;
        n1.valueIndex = n1._axisType === 'x' ? 0 : 1;
      } else {
        switch (n1._axisType) {
          case 'x':
            n1.xAxis = n1._value;
            break;
          case 'y':
            n1.yAxis = n1._value;
            break;
          default:
            break;
        }
      }
    };

    echart.series &&
      echart.series.forEach((n, i) => {
        const data = n.markLine && n.markLine.data;
        if (data) {
          data.forEach(n1 => {
            itemFn2(n1);
          });
        }
      });
  },

  fixEchartMarkArea(echart) {
    // 按系列名分配 markArea
    const markArea = echart.series && echart.series.markArea;
    if (markArea) {
      markArea.data.forEach((n, i) => {
        let serie = echart.series.find(n1 => n1.name === n[0]._serieName);
        if (!serie && !n[0]._serieName) {
          serie = echart.series[0];
        }
        if (!serie) {
          return;
        }
        if (!serie.markArea) {
          serie.markArea = {
            ...markArea,
            data: [],
          };
        }
        serie.markArea.data.push(n);
      });
    }

    echart.series &&
      echart.series.forEach(n => {
        const data = n.markArea && n.markArea.data;
        if (!data) {
          return;
        }
        data.forEach(n1 => {
          n1.forEach(n2 => {
            if (n2.xAxis === '') {
              delete n2.xAxis;
            }
            if (n2.yAxis === '') {
              delete n2.yAxis;
            }
          });
        });
      });
  },

  _getFieldKeyAndConf(key, pObj, ppObj) {
    let _conf;
    let _key;
    if (isArray(pObj)) {
      for (const i in ppObj) {
        if (ppObj[i] === pObj) {
          _key = `_${i}_${key}`;
          _conf = ppObj[_key];
          break;
        }
      }
    } else {
      _key = `_${key}`;
      _conf = pObj[_key];
    }
    return { _conf, _key };
  },

  // 根据私有配置开关，单位设置值
  fixEchartValues(obj, key = '', pObj = null, ppObj = null) {
    let _ppObj;
    if (!ppObj) {
      _ppObj = obj;
    } else {
      _ppObj = ppObj;
    }
    if (isArray(obj)) {
      obj.forEach((n, i) => {
        this.fixEchartValues(n, i, obj, pObj);
      });
    } else if (isObject(obj)) {
      Object.entries(obj).map(([i]) => {
        this.fixEchartValues(obj[i], i, obj, pObj);
      });
    } else {
      if (key !== '' && pObj) {
        if (pObj[key] === 'auto' || pObj[key] === null) {
          delete pObj[key];
          return;
        }

        const { _conf, _key } = this._getFieldKeyAndConf(key, pObj, _ppObj);
        if (_conf) {
          if (_conf.switch === false) {
            delete pObj[key];
          } else if (_conf.unit === '%') {
            pObj[key] = `${obj}%`;
          } else {}
        }
      }
    }
  },

  fixBar(option) {
    option.series.forEach((n, i) => {
      // 柱形图渐变色修改标签颜色
      if (n.label && !n.label.color) {
        const colorStops = n.itemStyle && n.itemStyle.color && n.itemStyle.color.colorStops;
        if (colorStops) {
          n.label.color = colorStops[0].color;
        } else {
          n.label.color = 'inherit';
        }
      }

      // 柱形图重叠设置
      if (n._stackName === 'overlap') {
        n.barGap = '-100%';
      }
    });
  },

  fixSerieDataBySerieType(option, echart, emptyName) {
    const xType = echart.xAxis && echart.xAxis.type;
    const yType = echart.yAxis && echart.yAxis.type;
    const isXYChart = xType || yType;
    if (isXYChart) {
      option.series.forEach(n => {
        n.data.forEach(n1 => {
          n1[0] = this._fixValByXYType(n1[0], xType, emptyName);
          n1[1] = this._fixValByXYType(n1[1], yType, emptyName);
        });
      });
    }
  },

  _fixValByXYType(val, xyType, emptyName) {
    let _val = val;
    if (xyType === 'value') {
      const _val1 = isNum(val) ? Number(val) : 0;
      _val = emptyName === 'tomographic' ? val : _val1;
    }
    return _val;
  },

  fixPie(option) {
    let center;
    option.series.forEach((n, i) => {
      if (n.type === 'pie') {
        if (i === 0) {
          center = n.center;
        } else {
          n.center = center;
        }
        if (n.label.show && n.label.position === 'center' && n.name !== 'total') {
          n.label.show = false;
          n.emphasis = { label: { show: true } };
        }
        if (n.label.position === 'outside') {
          // echart v5
          n.label.position = 'outer'; // echart v4
        }
      }
    });
  },

  // 标签增加千分数分割
  fixSerieLabelFormater(option) {
    option.series.forEach(n => {
      if (n.label && n.label.show && !n.label.formatter) {
        n.label.formatter = params => {
          const { data } = params;
          if (isArray(data)) {
            const val = option._tranXYAxis ? data[0] : data[1];
            return permil(val);
          }
          return null;
        };
      }
    });
  },

  // 时间轴格式化
  _fixTimeLabel(axis) {
    if (axis.type !== 'time') {
      return;
    }
    if (!axis.axisLabel) {
      axis.axisLabel = {};
    }
    if (axis.axisLabel.formatter) {
      return;
    }
    delete axis.axisLabel.interval;
    axis.axisLabel.showMaxLabel = true;
    axis.axisLabel.formatter = {
      year: '{MM}-{dd}\n{yyyy}',
      month: '{MM}-{dd}\n{yyyy}',
      day: '{MM}-{dd}\n{yyyy}',
      hour: '{HH}:{mm}',
      minute: '{HH}:{mm}',
      second: '{HH}:{mm}:{ss}',
      millisecond: '{MM}-{dd}\n{yyyy}',
      none: '{MM}-{dd}\n{yyyy}',
    };
  },

  // 时间轴显示完整时间格式
  fixTimeAxisLabel(option) {
    const arr = ['xAxis', 'yAxis'];
    arr.forEach(axisKey => {
      const axis = option[axisKey];
      if (!axis) {
        return true;
      }
      if (isArray(axis)) {
        axis.forEach(n => {
          this._fixTimeLabel(n);
        });
      } else {
        this._fixTimeLabel(axis);
      }
      return true;
    });
  },

  /**
   * 主题切换时改变form下有颜色主题默认值的属性值
   * @param  {Mix}    obj            对象
   * @param  {String} componentStyle 主题，dark|light
   * @param  {String} key            属性key
   * @param  {Object} pObj           父对象
   * @param  {String} path           属性路径
   */
  changeFormByCompStyle(obj, componentStyle, key = '', pObj = null, path = '') {
    if (isArray(obj)) {
      obj.forEach((n, i) => {
        const _path = path ? `${path}.${i}` : i;
        this.changeFormByCompStyle(n, componentStyle, '', null, _path);
      });
      return null;
    }
    if (isObject(obj)) {
      Object.entries(obj).map(([i]) => {
        const n = obj[i];
        const _path = path ? `${path}.${i}` : i;
        this.changeFormByCompStyle(n, componentStyle, i, obj, _path);
      });
      return null;
    }
    const _key = `_${key}`;
    let val = pObj && pObj[_key] && pObj[_key][componentStyle];
    if (val) {
      pObj[key] = val;
    } else {
      if (/color/i.test(key)) {
        val = this.getPropConfVal(path, componentStyle);
        if (typeof val !== 'undefined') {
          pObj[key] = val;
        }
      }
    }
    return null;
  },

  mergeBasic(option, echart) {
    const excludes = ['series', 'dataZoom', 'splitLine', 'backgroundColor'];
    for (const key in echart) {
      if (key.indexOf('_') === 0 || excludes.includes(key)) {
        continue;
      }
      if (!isArray(echart[key]) && !isObject(echart[key])) {
        option[key] = echart[key];
      } else {
        option[key] = mergeObj(option[key], echart[key]);
      }
    }
    option._tranXYAxis = echart._tranXYAxis;
  },

  mergeLegendSeries(option, echart) {
    const { _yzSeries, _nameSeries } = echart;

    // 按左右轴
    if (_yzSeries) {
      option.series.forEach((n, i) => {
        const item = _yzSeries.find(n1 => n1.name === n._yzName);
        if (item && item.type) {
          n.type = item.type;
        }
      });

      const data = option.legend && option.legend.data;
      data &&
        data.forEach((n, i) => {
          const item = _yzSeries.find(n1 => n1.name === n._yzName);
          if (item && item.legendIcon) {
            n.icon = item.legendIcon;
          }
        });
    }

    // 按图例名
    if (_nameSeries) {
      option.series.forEach((n, i) => {
        const item = _nameSeries.find(n1 => n1.name === n.name);
        if (item && item.type) {
          n.type = item.type;
        }
      });

      const data = option.legend && option.legend.data;
      if (data) {
        for (let i = 0; i < data.length; i++) {
          if (!isObject(data[i])) {
            data[i] = { name: data[i] };
          }

          const n = data[i];
          const item = _nameSeries.find(n1 => n1.name === n.name);
          if (item && item.legendIcon) {
            n.icon = item.legendIcon;
          }
        }
      }
    }
  },

  mergeSeries(option, echart) {
    option.series.forEach((n, i) => {
      mergeObj(n, echart.series[i]);
    });
  },

  _mergeDataZoomSlide(params) {
    const { n, echart, option } = params;
    if (n.show === true) {
      if (echart.xAxis.type === 'category') {
        const xAxisData = option.xAxis.data || option.xAxis._data;
        let { _barNum } = n;
        if (xAxisData.length >= _barNum * 2) {
          _barNum--;
        }
        n.end = (_barNum * 100) / xAxisData.length;
      }
    } else {
      n.end = 100;
    }

    // 时间颗粒度
    const xType = echart.xAxis?.type;
    const show = echart.dataZoom?.slider?.show;
    if (xType === 'time' && show) {
      const _conf = n._minValueSpan || {};
      switch (_conf.unit) {
        case 'day':
          n.minValueSpan = n.minValueSpan * 3600 * 24 * 1000;
          break;
        case 'minute':
          n.minValueSpan = n.minValueSpan * 60 * 1000;
          break;
        default:
          break;
      }
    }
  },

  mergeDataZoom(option, echart) {
    const { dataZoom } = echart;
    if (!dataZoom || !dataZoom.inside || !dataZoom.slider) {
      return;
    }

    option.dataZoom = [];
    const orient = dataZoom.inside.orient || 'horizontal';

    Object.entries(echart.dataZoom).map(([i]) => {
      const n = echart.dataZoom[i];
      n.orient = orient;

      if (i === 'slider') {
        this._mergeDataZoomSlide({ n, echart, option });
      }

      // 横向和纵向都支持缩放
      if (i === 'inside' && n.orient === 'horizontal_vertical') {
        const nh = JSON.parse(JSON.stringify(n));
        nh.orient = 'horizontal';
        option.dataZoom.push(nh);

        const nv = JSON.parse(JSON.stringify(n));
        nv.orient = 'vertical';
        option.dataZoom.push(nv);
        return true;
      }

      n.filterMode = 'none'; // 解决单轴折线图放大报错
      if (option.series?.[0]?.type === 'k') {
        delete n.filterMode;
      }
      option.dataZoom.push(n);
      return true;
    });

    // 同步缩放颗粒度
    const slider = option.dataZoom.find(n => n.type === 'slider');
    const show = echart.dataZoom?.slider?.show;
    if (show) {
      option.dataZoom.forEach(n => {
        n.minValueSpan = slider.minValueSpan;
      });
    }
  },

  mergeSplitLine(option, echart) {
    const { xAxis } = option;
    const yAxis = isArray(option.yAxis) ? option.yAxis[0] : option.yAxis;

    if (!xAxis || !yAxis) {
      return;
    }
    if (!xAxis.splitLine) {
      xAxis.splitLine = { show: false };
    }
    if (!yAxis.splitLine) {
      yAxis.splitLine = {};
    }

    if (!echart.splitLine) {
      return;
    }
    mergeObj(xAxis.splitLine, echart.splitLine);
    mergeObj(yAxis.splitLine, echart.splitLine);
    xAxis.splitLine.show = echart.splitLine.show[0];
    yAxis.splitLine.show = echart.splitLine.show[1];
  },

  getLabelFormatStr(_format, data) {
    let text = '';
    if (_format) {
      text = _format;
      let obj;
      if (isObject(data)) { // 数据是对象形式，如漏斗图
        obj = data;
      } else { // 数据是数组形式，如果柱形图，饼图
        obj = data[data.length - 1]; // 原对象数据必须约定放在最后一位
        if (typeof obj === 'string') {
          obj = getObjFromJson(obj);
        }
      }

      if (obj) {
        Object.entries(obj).map(([key, val]) => {
          const regex = new RegExp(`\{${key}\}`, 'g');
          const numStr = numFormat(val, true);
          text = text.replace(regex, numStr);
        });
      }
    }
    return text;
  },

  mergeSeriesLabels(option, echart) {
    if (!echart.series._labels) {
      return;
    }
    let labels = echart.series._labels;

    // 排序
    const orders = { all: 0, 'all_bar': 1, 'all_line': 1, 'serie_name': 100 };
    labels.forEach(n => (n.order = orders[n._forType]));
    labels = orderBy(labels, ['order'], ['asc']);

    // 分配
    labels.forEach(n => {
      const newLabel = JSON.parse(JSON.stringify(n));
      const { _unit, _format } = newLabel;
      if (_unit || _format) {
        const index = echart._tranXYAxis ? 0 : 1;
        newLabel.formatter = params => {
          const { data } = params;
          let text = this.getLabelFormatStr(_format, data) || numFormat(data[index], true);
          text = `${text}${_unit}`;
          return text;
        };
      }

      if (n._forType === 'all') {
        option.series.forEach(serie => {
          serie.label = this._cloneNewLabel(newLabel);
        });
      } else if (n._forType.indexOf('all_') === 0) {
        const type = n._forType.replace('all_', '');
        option.series.forEach(serie => {
          if (serie.type === type) {
            serie.label = this._cloneNewLabel(newLabel);
          }
        });
      } else if (n._forType === 'serie_name') {
        option.series.forEach(serie => {
          if (serie.name === n._serieName) {
            serie.label = this._cloneNewLabel(newLabel);
          }
        });
      } else {}
    });
  },

  _cloneNewLabel(newLabel) {
    const label = JSON.parse(JSON.stringify(newLabel));
    if (newLabel.formatter) {
      label.formatter = newLabel.formatter;
    }
    return label;
  },

  // 原生tooltip获取x轴标签
  getXaxisValue(params) {
    if (isArray(params.value)) {
      return params.value[0];
    } else {
      let val = params.axisValue;
      if (typeof val === 'number' && /^\d{13}$/.test(`${val}`)) {
        val = timeFormat(new Date(params.axisValue));
      }
      return val;
    }
  },

  // 换行替换
  replaceLineWrap(option) {
    const replace = text => {
      const _text = String(text);
      return _text.replace(/\\n/g, '\n');
    };
    const { xAxis = {}, yAxis = {} } = option;
    xAxis.name && (xAxis.name = replace(xAxis.name));
    yAxis.name && (yAxis.name = replace(yAxis.name));
  },

  fixLegend(option) {
    const { legend } = option;
    if (legend && legend.icon === 'line') {
      legend.icon = 'rect';
      legend.itemWidth = 12;
      legend.itemHeight = 2;
      const isFunnel = option?.series?.[0]?.type === 'funnel'; // 漏斗图需要3才能显示线
      legend.itemHeight = isFunnel ? 3 : 2;
    }
  },

  fixLegendPos(option, orgEchart) {
    const { _top = {}, _bottom = {}, _left = {}, _right = {} } = orgEchart.legend || {};
    if (_top.switch || _bottom.switch || _left.switch || _right.switch) {
      if (!option.legend) {
        option.legend = {};
      }
    }
    if (_top.switch) {
      option.legend.top = orgEchart.legend.top;
      delete option.legend.bottom;
      _bottom.switch = false;
    }
    if (_bottom.switch) {
      option.legend.bottom = orgEchart.legend.bottom;
      delete option.legend.top;
    }
    if (_left.switch) {
      option.legend.left = orgEchart.legend.left;
      delete option.legend.right;
      _right.switch = false;
    }
    if (_right.switch) {
      option.legend.right = orgEchart.legend.right;
      delete option.legend.left;
    }
  },
};
